package com.tqfframe.test.xmlscript;
import org.dom4j.*;
import org.dom4j.io.OutputFormat;
import org.dom4j.io.XMLWriter;

import java.io.IOException;
import java.io.StringWriter;
import java.util.*;

/**
 * @Author: 唐祺峰
 * @Date: 2020/11/5 0005 9:03
 * @Version 1.0
 */
public class XmlUtils {

    /**
     * xml转map
     */
    public static Map xmlmapWithAttr(String xmlStr) throws DocumentException {
        Document doc = DocumentHelper.parseText(xmlStr);
        Element root = doc.getRootElement();
        Map<String, Object> map = (Map<String, Object>) xmlmapWithAttr(root);
        if(root.elements().size()==0 && root.attributes().size()==0){
            return map;
        }
        Map<String, Object> rootMap = new HashMap<String, Object>();
        rootMap.put(root.getName(), map);
        return rootMap;
    }


    private static Map xmlmapWithAttr(Element element) {
        Map<String, Object> map = new LinkedHashMap<String, Object>();
        List<Element> list = element.elements();
        List<Attribute> listAttr0 = element.attributes(); // 当前节点的所有属性的list
        for (Attribute attr : listAttr0) {
            map.put("@" + attr.getName(), attr.getValue());
        }
        if (list.size() > 0) {

            for (int i = 0; i < list.size(); i++) {
                Element iter = list.get(i);
                List mapList = new ArrayList();
                if (iter.elements().size() > 0) {
                    Map m = xmlmapWithAttr(iter);
                    if (map.get(iter.getName()) != null) {
                        Object obj = map.get(iter.getName());
                        if (!(obj instanceof List)) {
                            mapList = new ArrayList();
                            mapList.add(obj);
                            mapList.add(m);
                        }
                        if (obj instanceof List) {
                            mapList = (List) obj;
                            mapList.add(m);
                        }
                        map.put(iter.getName(), mapList);
                    } else
                        map.put(iter.getName(), m);
                } else {

                    List<Attribute> listAttr = iter.attributes(); // 当前节点的所有属性的list
                    Map<String, Object> attrMap = null;
                    boolean hasAttributes = false;
                    if (listAttr.size() > 0) {
                        hasAttributes = true;
                        attrMap = new LinkedHashMap<String, Object>();
                        for (Attribute attr : listAttr) {
                            attrMap.put("@" + attr.getName(), attr.getValue());
                        }
                    }

                    if (map.get(iter.getName()) != null) {
                        Object obj = map.get(iter.getName());
                        if (!(obj instanceof List)) {
                            mapList = new ArrayList();
                            mapList.add(obj);
                            // mapList.add(iter.getText());
                            if (hasAttributes) {
                                attrMap.put("#text", iter.getText());
                                mapList.add(attrMap);
                            } else {
                                mapList.add(iter.getText());
                            }
                        }
                        if (obj instanceof List) {
                            mapList = (List) obj;
                            // mapList.add(iter.getText());
                            if (hasAttributes) {
                                attrMap.put("#text", iter.getText());
                                mapList.add(attrMap);
                            } else {
                                mapList.add(iter.getText());
                            }
                        }
                        map.put(iter.getName(), mapList);
                    } else {
                        // map.put(iter.getName(), iter.getText());
                        if (hasAttributes) {
                            attrMap.put("#text", iter.getText());
                            map.put(iter.getName(), attrMap);
                        } else {
                            map.put(iter.getName(), iter.getText());
                        }
                    }
                }
            }
        } else {
            // 根节点的
            if (listAttr0.size() > 0) {
                map.put("#text", element.getText());
            } else {
                map.put(element.getName(), element.getText());
            }
        }
        return map;
    }

    /**
     * map转xml
     */
    public static Document mapxml(Map<String, Object> map) throws DocumentException, IOException  {
        Iterator<Map.Entry<String, Object>> entries = map.entrySet().iterator();
        if(entries.hasNext()){ //获取第一个键创建根节点
            Map.Entry<String, Object> entry = entries.next();
            Document doc = DocumentHelper.createDocument();
            Element root = DocumentHelper.createElement(entry.getKey());
            doc.add(root);
            mapxml((Map)entry.getValue(), root);
            //System.out.println(doc.asXML());
            //System.out.println(formatXml(doc));
            return doc;
        }
        return null;
    }

    private static Element mapxml(Map<String, Object> map, Element body) {
        Iterator<Map.Entry<String, Object>> entries = map.entrySet().iterator();
        while (entries.hasNext()) {
            Map.Entry<String, Object> entry = entries.next();
            String key = entry.getKey();
            Object value = entry.getValue();
            if(key.startsWith("@")){ //属性
                body.addAttribute(key.substring(1, key.length()), value.toString());
            } else if(key.equals("#text")){ //有属性时的文本
                body.setText(value.toString());
            } else {
                if(value instanceof java.util.List ){
                    List list = (List)value;
                    Object obj;
                    for(int i=0; i<list.size(); i++){
                        obj = list.get(i);
                        //list里是map或String，不会存在list里直接是list的，
                        if(obj instanceof java.util.Map){
                            Element subElement = body.addElement(key);
                            mapxml((Map)list.get(i), subElement);
                        } else {
                            body.addElement(key).setText((String)list.get(i));
                        }
                    }
                } else if(value instanceof java.util.Map ){
                    Element subElement = body.addElement(key);
                    mapxml((Map)value, subElement);
                } else {
                    body.addElement(key).setText(value.toString());
                }
            }
            //System.out.println("Key = " + entry.getKey() + ", Value = " + entry.getValue());
        }
        return body;
    }

    /**
     * 格式化输出xml
     */
    public static String formatXml(Document document) throws DocumentException, IOException  {
        // 格式化输出格式
        OutputFormat format = OutputFormat.createPrettyPrint();
        //format.setEncoding("UTF-8");
        StringWriter writer = new StringWriter();
        // 格式化输出流
        XMLWriter xmlWriter = new XMLWriter(writer, format);
        // 将document写入到输出流
        xmlWriter.write(document);
        xmlWriter.close();
        return writer.toString();
    }

    /**
     * map对比
     */
    public static void dealMap(Map<String, Object> oldMap,Map<String, Object> newMap){
        if(oldMap!=null){
            for(Map.Entry<String, Object> childMap:newMap.entrySet()){
                String elementName=childMap.getKey();
                if(!(childMap.getValue() instanceof Map)){
                    if(!oldMap.containsKey(elementName)){
                        oldMap.put(elementName, childMap.getValue());
                    }
                    continue;
                }
                Map linkMap= (Map) childMap.getValue();
                if(!oldMap.containsKey(elementName)){
                    oldMap.put(elementName, childMap.getValue());
                }
                if(linkMap.size()>0){
                    if(oldMap.get(elementName) instanceof Map){
                        dealMap(linkMap,(Map<String, Object>) oldMap.get(elementName));
                    }
                }
            }
        }

    }


    /**
     * 脚本替换
     */
    public static String updataXml(String xml,String type,String pageName) {
        if(type.equals("project")){
            xml=xml.replaceAll("<"+pageName+"", "<plugin:"+pageName+" xmlns:plugin=\"http://pupuwang.com/plugin\"");
            xml=xml.replaceAll("</"+pageName+">", "</plugin:"+pageName+">");
        }
        if(type.equals("page")){
            xml=xml.replaceAll("<"+pageName+"", "<define:"+pageName+" xmlns:plugin=\"http://pupuwang.com/plugin\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:define=\"http://pupuwang.com/define\"");
            xml=xml.replaceAll("</"+pageName+">", "</define:"+pageName+">");
        }
        if(type.equals("view")){
            xml= xml.replaceAll("<"+pageName+"", "<define:"+pageName+"  xmlns:plugin=\"http://pupuwang.com/plugin\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n" +
                    "             xmlns:define=\"http://pupuwang.com/define\"");
            xml=xml.replaceAll("</"+pageName+">", "</define:"+pageName+">");
        }
        if(type.equals("tag")){
            xml=xml.replaceAll("<"+pageName+"", "<define:"+pageName+" xmlns:define=\"http://pupuwang.com/define\"\n" +
                    "                          xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:plugin=\"http://pupuwang.com/plugin\"");
            xml=xml.replaceAll("</"+pageName+">", "</define:"+pageName+">");
        }
        return xml;
    }


}

